#ifndef VSqlTable_H
#define VSqlTable_H					 

#include "VSqlFields.h"
#include "VSqlDatabase.h"
#include "VSqlGenId.h"

///////////////////////////////////////////////////////////////////////////////
class VSqlTableReg;
///////////////////////////////////////////////////////////////////////////////

class VSqlTablesReg
{
public:
	VSqlTablesReg() {}

	void append(VSqlTableReg *v) { m_list << v;}

	static VSqlTablesReg *singleton() {	static VSqlTablesReg s; return &s;}
	static void registerInDb();

private:
	QList<VSqlTableReg*> m_list;
};

///////////////////////////////////////////////////////////////////////////////

class VSqlTableReg
{
public:
	VSqlTableReg(VSqlTablesReg *tablesReg) { tablesReg->append(this);}
	virtual ~VSqlTableReg() {}

	virtual void registerInDb() = 0;
};

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////

class VSqlTableModel : public QSqlTableModel
{
	Q_OBJECT

public:
	VSqlTableModel(QObject *parent = NULL);
	
public:
	Qt::ItemFlags flags(const QModelIndex &index) const;
	QVariant headerData(int section,Qt::Orientation orientation,int role = Qt::DisplayRole) const;
	QVariant data(const QModelIndex &index,int role) const;
};

///////////////////////////////////////////////////////////////////////////////

class VSqlTable
{
public:
	VSqlTable(const QString &tableName = QString());
	~VSqlTable();

	void setName(const QString &v) { m_name = v;}
	QString name() const { return m_name;}

	QString unicode() const { selectTableInfo(); return m_fieldInfo->unicode();}

	void setCreateDT(const QDateTime &v) { m_fieldInfo->setCreateDT(v);}
	QDateTime createDT() const { selectTableInfo(); return m_fieldInfo->createDT();}

	void setAutor(const QString &v) { m_fieldInfo->setAutor(v);}
	QString autor() const { selectTableInfo(); return m_fieldInfo->autor();}

	void setComment(const QString &v) { m_fieldInfo->setComment(v);}
	QString comment() const { selectTableInfo(); return m_fieldInfo->comment();}

	VSqlFieldsPtr fieldsPtr() const { return m_fieldsPtr;}
	//operator VSqlFieldsPtr() const { return m_fieldsPtr;}

	QString selectRecordsAsSql(const QString &sqlOrderBy = QString()) const;

	void registerInDb();
	
public:
	static void createTable(const QString &tableName,const VSqlFields &fields) { fields.createTable(tableName);}

	VSqlFields selectFields() const;

	QList<QSqlRecord> selectRecords(const QString &sqlWhere = QString()) const;
	void updateRecords(const QSqlRecord &record,const QString &sqlWhere = QString());
	
	static VSqlFieldPtr toFieldFrom(const VSqlFieldRefIdPtr &fieldRefId);
	static VSqlFieldPtr toFieldFrom(const VSqlFieldRefStringPtr &fieldRefString);
	static VSqlFieldPtr toFieldFrom(const VSqlFieldListIdPtr &fieldListId);

private:
	void selectTableInfo() const { m_fieldInfo->select(m_name);}
	
private:
	QString m_name;
	VSqlFieldInfo *m_fieldInfo;
	bool m_tableInfoIsSelect;
	VSqlFieldsPtr m_fieldsPtr;
	//m_existingFields;
};

typedef QSharedPointer<VSqlTable> VSqlTablePtr;

///////////////////////////////////////////////////////////////////////////////

class VSqlTableListId
{
public:
	static const QString tName(const QString &tableName) { return QString() + tableName + VSqlRegTables::listId();}
	static const QString fId() { return "fId";}
	static const QString fToTableName() { return "fToTableName";}
	static const QString fToId() { return "fToId";}

	static void registerInDb(const QString &tableName);
};

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////

class VSqlRegTablesDN : public VSqlTableReg
{
public:
	VSqlRegTablesDN(VSqlTablesReg *tablesReg) :VSqlTableReg(tablesReg) {}

	static const QString tName() { return "VRegTablesDN";}
	static const QString fUnicode() { return "fUnicode";}
	static const QString fLang() { return "fLang";}
	static const QString fDisplayName() { return "fDisplayName";}

	virtual void registerInDb();

private:
	static VSqlRegTablesDN m_singleton;
};

///////////////////////////////////////////////////////////////////////////////

class VSqlRegTablesACT : public VSqlTableReg
{
public:
	VSqlRegTablesACT(VSqlTablesReg *tablesReg) :VSqlTableReg(tablesReg) {}

	static const QString tName() { return "VRegTablesACT";}
	static const QString fUnicode() { return "fUnicode";}
	static const QString fInsert() { return "fInsert";}
	static const QString fDelete() { return "fDelete";}
	static const QString fUpdate() { return "fUpdate";}
	static const QString fSelect() { return "fSelect";}

	virtual void registerInDb();

private:
	static VSqlRegTablesACT m_singleton;
};

///////////////////////////////////////////////////////////////////////////////

class VSqlRegTablesFORM : public VSqlTableReg
{
public:
	VSqlRegTablesFORM(VSqlTablesReg *tablesReg) :VSqlTableReg(tablesReg) {}

	static const QString tName() { return "VRegTablesFORM";}
	static const QString fUnicode() { return "fUnicode";}
	static const QString fFormName() { return "fFormName";}
	static const QString fScript() { return "fScript";}

	virtual void registerInDb();

private:
	static VSqlRegTablesFORM m_singleton;
};

///////////////////////////////////////////////////////////////////////////////
/*
class VSqlRegTablesExt : public VSqlTableReg
{
public:
	VSqlRegTablesExt(VSqlTablesReg *tablesReg) :VSqlTableReg(tablesReg) {}

	static const QString tName() { return "VRegTablesExt";}
	static const QString fRegTables() { return "fRegTables";}
	static const QString fDisplayName() { return "fDisplayName";}
	static const QString fForms() { return "fForms";}
	static const QString fActions() { return "fActions";}

	virtual void registerInDb();

private:
	static VSqlRegTablesExt m_singleton;
};
*/
///////////////////////////////////////////////////////////////////////////////

#endif
